import { HYEventStore } from 'hy-event-store'
import { getSongDetail, getSongLyric } from "../services/player"
import { parseLyric } from "../utils/parse-lyric"

// 创建音频实例
/**
  const innerAudioContext = wx.createInnerAudioContext({
    useWebAudioImplement: false // 是否使用 WebAudio 作为底层音频驱动，默认关闭。对于短音频、播放频繁的音频建议开启此选项，开启后将获得更优的性能表现。由于开启此选项后也会带来一定的内存增长，因此对于长音频建议关闭此选项
  })
  innerAudioContext.src = 'https://wx_test.mp3'
  innerAudioContext.play() // 播放
  innerAudioContext.pause() // 暂停
  innerAudioContext.stop() // 停止
  innerAudioContext.destroy() // 释放音频资源
*/
export const audioContext = wx.createInnerAudioContext()

const playerStore = new HYEventStore({
  state: {
    playSongList: [],
    playSongIndex: 0,

    id: 0,
    currentSong: {},
    currentTime: 0,
    durationTime: 0,
    lyricInfos: [],
    currentLyricText: "",
    currentLyricIndex: -1,

    isFirstPlay: true,

    isPlaying: false,
    playModeIndex: 0, // 0:顺序播放 1:单曲循环 2:随机播放
  },

  actions: {
    // 1.根据id请求数据
    playMusicWithSongIdAction(ctx, id) {
      // 0.原来的数据重置
      ctx.currentSong = {};
      ctx.durationTime = 0;
      ctx.durationTime = 0;
      ctx.currentLyricIndex = 0;
      ctx.currentLyricText = "";
      ctx.lyricInfos = [];

      // 1.保存id
      ctx.id = id;
      ctx.isPlaying = true;

      // 2.请求歌曲相关的数据
      // 2.1.根据id获取歌曲的详情
      getSongDetail(id).then((res) => {
        ctx.currentSong = res.songs[0];
        ctx.durationTime = res.songs[0].dt;
      });

      // 2.2.根据id获取歌词的信息
      getSongLyric(id).then((res) => {
        const lrcString = res.lrc.lyric;
        const lyricInfos = parseLyric(lrcString);
        ctx.lyricInfos = lyricInfos;
      });

      // 3.播放当前的歌曲
      audioContext.stop();
      audioContext.src = `https://music.163.com/song/media/outer/url?id=${id}.mp3`;
      audioContext.autoplay = true;

      // 4.监听播放的进度
      if (ctx.isFirstPlay) {
        ctx.isFirstPlay = false

        audioContext.onTimeUpdate(() => {
          // 1.获取当前播放的时间
          ctx.currentTime = audioContext.currentTime * 100

          // 2.匹配正确的歌词
          if (ctx.lyricInfos.length) return
          let index = ctx.lyricInfos.length - 1;
          for (let i = 0; i < ctx.lyricInfos.length; i++) {
            const info = ctx.lyricInfos[i];
            if (info.time > audioContext.currentTime * 1000) {
              index = i - 1;
              break;
            }
          }
          if (index === ctx.currentLyricIndex) return;

          // 3.获取歌词的索引index和文本text
          // 4.改变歌词滚动页面的位置
          const currentLyricText = ctx.lyricInfos[index].text;
          ctx.currentLyricText = currentLyricText;
          ctx.currentLyricIndex = index;
        })
        // 监听音频加载中事件。当音频因为数据不足，需要停下来加载时会触发
        audioContext.onWaiting(() => {
          audioContext.pause(); // 暂停
        });
        // 监听音频进入可以播放状态的事件。但不保证后面可以流畅播放
        audioContext.onCanplay(() => {
          audioContext.play(); // 播放
        });
        // 监听音频自然播放至结束的事件
        audioContext.onEnded(() => {
          // 如果是单曲循环, 不需要切换下一首歌
          if (audioContext.loop) return;

          // 切换下一首歌曲
          this.dispatch("playNewMusicAction");
        });
      }
    },

    // 播放或暂停音乐
    changeMusicStatusAction(ctx) {
      if (!audioContext.paused) {
        audioContext.pause(); // 暂停
        ctx.isPlaying = false;
      } else {
        audioContext.play(); // 播放
        ctx.isPlaying = true;
      }
    },

    // 切换播放模式: 顺序播放, 随机播放, 单曲循环
    changePlayModeAction(ctx) {
      // 1.计算新的模式
      let modeIndex = ctx.playModeIndex;
      modeIndex = modeIndex + 1;
      if (modeIndex === 3) modeIndex = 0;

      // 设置是否是单曲循环
      if (modeIndex === 1) {
        audioContext.loop = true;
      } else {
        audioContext.loop = false;
      }

      // 2.保存当前的模式
      ctx.playModeIndex = modeIndex;
    },

    // 播放新歌曲
    playNewMusicAction(ctx, isNext = true) {
      // 1.获取之前的数据
      const length = ctx.playSongList.length;
      let index = ctx.playSongIndex;

      // 2.根据之前的数据计算最新的索引
      switch (ctx.playModeIndex) {
        case 1:
        case 0: // 顺序播放
          index = isNext ? index + 1 : index - 1;
          if (index === length) index = 0;
          if (index === -1) index = length - 1;
          break;
        case 2: // 随机播放
          index = Math.floor(Math.random() * length);
          break;
      }

      // 3.根据索引获取当前歌曲的信息
      const newSong = ctx.playSongList[index];

      // 开始播放新的歌曲
      this.dispatch("playMusicWithSongIdAction", newSong.id);

      // 4.保存最新的索引值
      ctx.playSongIndex = index;
    },

  }
})

export default playerStore;
